package com.minelx.datamicroscope.core.display;

import com.minelx.datamicroscope.core.query.Query;
import com.minelx.datamicroscope.core.query.Resource;
import com.minelx.datamicroscope.core.query.ResourceMapping;
import com.minelx.hellopandas.core.DataFrame;
import com.minelx.hellopandas.core.JoinOption;
import com.minelx.hellopandas.core.Pandas;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.toList;

public class JoiningMerger implements Merger {

	private static final String DEFAULT_JOIN_METHOD = "left";

	private final Map<String, String> howMapping;

	JoiningMerger(Map<String, String> howMapping) {
		this.howMapping = howMapping;
	}

	@Override
	public DataFrame merge(List<ResourceMapping> files, String destinationURI) {
		List<ResourceMapping> mergedResourceFiles = new ArrayList<>(files);
		ResourceMapping firstResourceFile = mergedResourceFiles.remove(0);

		return Pandas.of(Query.localPandas()).dataFrame(Query.localPandas().mergeAll(
				firstResourceFile.resource().dataFrame().description(),
				mergedResourceFiles.stream().map(this::toJoinOption).collect(toList()),
				destinationURI));
	}

	private JoinOption toJoinOption(ResourceMapping resourceMapping) {
		Resource resource = resourceMapping.resource();
		List<String> mergingGaps = resource.clues();
		return new JoinOption(resource.dataFrame().description(),
				getHow(resourceMapping.name()),
				mergingGaps,
				mergingGaps);
	}

	private String getHow(String resourceName) {
		if (!howMapping.containsKey(resourceName)) {
			return DEFAULT_JOIN_METHOD;
		}
		return howMapping.get(resourceName);
	}
}
